package modalities;

import java.io.FileReader;
import java.util.Locale;
import java.util.Observable;
import java.util.Observer;

import javax.speech.Central;
import javax.speech.Engine;
import javax.speech.EngineModeDesc;
import javax.speech.recognition.Recognizer;
import javax.speech.recognition.RecognizerAudioAdapter;
import javax.speech.recognition.RuleGrammar;

/**
 * Class that interact with the vista voice recognition system.
 *
 */
public class Voice implements Observer {

	String name;
	ObservableThing contactToDecider;
	Recognizer rec;
	//Component that recognize words
	VoiceRecognition vrc;
	//Component that check the soundLevel
	AudioLevelListener all;

	/**
	 * 
	 * String mot = Windows.voir.recongnise();
	 * 	
	 * if mot.eqauals(Fire)
	 * 
	 */
	public Voice(String name, Decider observer)
	{

		this.contactToDecider = new ObservableThing();
		this.name = name;
		//Add the decider as observer.
		contactToDecider.addObserver(observer);
		initialize();
	}

	public void initialize(){
		try {
			// Create a recognizer that supports English.
			rec = Central.createRecognizer(new EngineModeDesc(Locale.FRANCE));

			all = new AudioLevelListener(this);
			vrc = new VoiceRecognition(this);

			RecognizerAudioAdapter raud = new RecognizerAudioAdapter();
			rec.getAudioManager().addAudioListener(raud);
			rec.getAudioManager().addAudioListener(all);

			rec.allocate();// Start up the recognizer
			// Load the grammar from a file, and enable it
			FileReader reader = new FileReader("grammar.txt");
			RuleGrammar gram = rec.loadJSGF(reader);
			gram.setEnabled(true);
			rec.waitEngineState(Engine.ALLOCATED);

			rec.addResultListener(vrc);// Add the listener to get results
			// Commit the grammar
			rec.commitChanges();

			rec.requestFocus();// Request focus and start listening

			//At the beginning don't need to be active
			setVoiceRecogActivationState(false);


		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	@Override
	public String toString(){
		return new String(this.name);
	}



	public void setLevelActivationState(Boolean state)
	{
		all.setActivated(state);

		try {

			if(state){ // ON
				rec.resume();
			}
			else {	//OFF
				rec.pause();
			}

		} catch (Exception e) {e.printStackTrace();}

	}

	public void setVoiceRecogActivationState(Boolean state) {

		try {

			if(state){ // ON
				rec.resume();
			}
			else {	//OFF
				rec.pause();
			}

		} catch (Exception e) {e.printStackTrace();}

		vrc.setActivationState(state);

	}


	@Override
	public void update(Observable o, Object arg) {
		contactToDecider.externalSetChanged();
		contactToDecider.notifyObservers(arg);
	}
}
